﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using RotovapPlatform.Domain.Equipment.Device.IO;
using RotovapPlatform.Domain.Equipment.Interfaces.Base;
using RotovapPlatform.Domain.Equipment.Interfaces.Services;

namespace RotovapPlatform.Application.Services.Devices
{
	/// <summary>
	/// IO信号应用服务
	/// 提供统一的IO信号访问入口，封装底层信号操作细节
	/// </summary>
	public class IOSignalAppService : IIOSignalAppService, IDisposable
	{
		private readonly IIOModuleService _ioModuleService;
		private readonly IIOSignalManager _signalManager;
		private readonly ILogger<IOSignalAppService> _logger;

		private readonly CancellationTokenSource _cts = new();
		private Task _pollingTask;
		private bool _isRunning;
		private bool _disposed;

		// 冷凝器压力状态缓存
		private double _condenserPressure;

		// 状态回调函数
		private readonly List<Func<string, object, Task>> _stateCallbacks = new();

		/// <summary>
		/// 信号状态变化事件
		/// </summary>
		public event EventHandler<IOSignalStateChangedEventArgs> SignalStateChanged;

		/// <summary>
		/// 构造函数
		/// </summary>
		public IOSignalAppService(
			IIOModuleService ioModuleService,
			IIOSignalManager signalManager,
			ILogger<IOSignalAppService> logger)
		{
			_ioModuleService = ioModuleService ?? throw new ArgumentNullException(nameof(ioModuleService));
			_signalManager = signalManager ?? throw new ArgumentNullException(nameof(signalManager));
			_logger = logger ?? throw new ArgumentNullException(nameof(logger));

			// 订阅信号管理器的状态变化事件
			_signalManager.SignalStateChanged += OnSignalStateChanged;

			// 注册所有IO信号
			RegisterIOSignals();
		}

		/// <summary>
		/// 注册IO信号
		/// </summary>
		private void RegisterIOSignals()
		{
			try
			{
				// 注册DI信号
				foreach (DISignalId id in Enum.GetValues(typeof(DISignalId)))
				{
					var signal = DISignal.Create(id);
					_signalManager.RegisterDISignal(signal);
				}

				// 注册DO信号
				foreach (DOSignalId id in Enum.GetValues(typeof(DOSignalId)))
				{
					// 创建DO信号时，传入写入函数
					var signal = DOSignal.Create(id, null,
						async (channel, state) => await _ioModuleService.WriteDOAsync(channel, state));
					_signalManager.RegisterDOSignal(signal);
				}

				// 注册AI信号
				_signalManager.RegisterAISignal(AISignal.Create(
					AISignalId.CondenserPressure,
					"冷凝器压力", 0, 1000, "mbar"));
				_signalManager.RegisterAISignal(AISignal.Create(
					AISignalId.HeatingTemperature,
					"加热温度", 0, 200, "°C"));
				_signalManager.RegisterAISignal(AISignal.Create(
					AISignalId.CondenserTemperature,
					"冷凝器温度", -10, 50, "°C"));

				_logger.LogInformation("所有IO信号注册完成");
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "注册IO信号异常");
			}
		}

		/// <summary>
		/// 启动服务
		/// </summary>
		public async Task StartAsync()
		{
			if (_isRunning) return;

			_isRunning = true;
			_pollingTask = PollingSignalsAsync(_cts.Token);

			await Task.CompletedTask;
			_logger.LogInformation("IO信号应用服务已启动");
		}

		/// <summary>
		/// 停止服务
		/// </summary>
		public async Task StopAsync()
		{
			if (!_isRunning) return;

			_isRunning = false;
			_cts.Cancel();

			if (_pollingTask != null)
			{
				await _pollingTask;
				_pollingTask = null;
			}

			_logger.LogInformation("IO信号应用服务已停止");
		}

		/// <summary>
		/// 信号轮询任务
		/// </summary>
		private async Task PollingSignalsAsync(CancellationToken ct)
		{
			while (!ct.IsCancellationRequested)
			{
				try
				{
					// 刷新所有信号状态
					await RefreshAllSignalsAsync();

					// 轮询间隔
					await Task.Delay(100, ct);
				}
				catch (OperationCanceledException)
				{
					break;
				}
				catch (Exception ex)
				{
					_logger.LogError(ex, "IO信号轮询异常");
					await Task.Delay(1000, ct);
				}
			}
		}

		/// <summary>
		/// 强制刷新所有IO信号状态
		/// </summary>
		public async Task RefreshAllSignalsAsync()
		{
			try
			{
				// 读取DI信号
				int diStates = await _ioModuleService.ReadAllDIAsync();
				_signalManager.UpdateDISignalStates(diStates);

				// 读取冷凝器压力值
				_condenserPressure = await _ioModuleService.GetCondenserPressureAsync();
				_signalManager.UpdateAISignalValue(AISignalId.CondenserPressure, _condenserPressure);

				// 模拟其他模拟量数据（实际项目中应从硬件读取）
				_signalManager.UpdateAISignalValue(AISignalId.HeatingTemperature,
					25 + Math.Sin(DateTime.Now.Second / 10.0) * 5);
				_signalManager.UpdateAISignalValue(AISignalId.CondenserTemperature,
					5 + Math.Sin(DateTime.Now.Second / 15.0) * 2);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "刷新IO信号状态异常");
			}
		}

		/// <summary>
		/// 获取所有DI信号
		/// </summary>
		public IReadOnlyDictionary<string, IDISignal> GetAllDISignals()
		{
			return _signalManager.DISignals;
		}

		/// <summary>
		/// 获取所有DO信号
		/// </summary>
		public IReadOnlyDictionary<string, IDOSignal> GetAllDOSignals()
		{
			return _signalManager.DOSignals;
		}

		/// <summary>
		/// 获取所有AI信号
		/// </summary>
		public IReadOnlyDictionary<string, IAISignal> GetAllAISignals()
		{
			return _signalManager.AISignals;
		}

		/// <summary>
		/// 获取DI信号
		/// </summary>
		public IDISignal GetDISignal(DISignalId id)
		{
			return _signalManager.GetDISignal(id);
		}

		/// <summary>
		/// 获取DO信号
		/// </summary>
		public IDOSignal GetDOSignal(DOSignalId id)
		{
			return _signalManager.GetDOSignal(id);
		}

		/// <summary>
		/// 获取AI信号
		/// </summary>
		public IAISignal GetAISignal(AISignalId id)
		{
			return _signalManager.GetAISignal(id);
		}

		/// <summary>
		/// 获取DI信号状态
		/// </summary>
		public bool GetDIState(DISignalId id)
		{
			var signal = _signalManager.GetDISignal(id);
			return signal?.State ?? false;
		}

		/// <summary>
		/// 获取DO信号状态
		/// </summary>
		public bool GetDOState(DOSignalId id)
		{
			var signal = _signalManager.GetDOSignal(id);
			return signal?.State ?? false;
		}

		/// <summary>
		/// 获取AI信号值
		/// </summary>
		public double GetAIValue(AISignalId id)
		{
			var signal = _signalManager.GetAISignal(id);
			return signal?.Value ?? 0;
		}

		/// <summary>
		/// 设置DO信号状态
		/// </summary>
		public async Task<bool> SetDOStateAsync(DOSignalId id, bool state)
		{
			return await _signalManager.SetDOSignalStateAsync(id, state);
		}

		/// <summary>
		/// 获取冷凝器压力值
		/// </summary>
		public double GetCondenserPressure()
		{
			return _condenserPressure;
		}

		/// <summary>
		/// 注册信号状态变化回调函数
		/// </summary>
		public void RegisterStateChangeCallback(Func<string, object, Task> callback)
		{
			if (callback != null)
			{
				_stateCallbacks.Add(callback);
			}
		}

		/// <summary>
		/// 信号状态变化处理
		/// </summary>
		private void OnSignalStateChanged(object sender, IOSignalStateChangedEventArgs e)
		{
			try
			{
				// 转发事件
				SignalStateChanged?.Invoke(this, e);

				// 调用所有注册的回调函数
				foreach (var callback in _stateCallbacks)
				{
					try
					{
						_ = callback(e.SignalId, e.NewState);
					}
					catch (Exception ex)
					{
						_logger.LogError(ex, "信号状态变化回调执行异常");
					}
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "处理信号状态变化事件异常");
			}
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		protected virtual void Dispose(bool disposing)
		{
			if (_disposed) return;

			if (disposing)
			{
				try
				{
					// 停止服务
					if (_isRunning)
					{
						_ = StopAsync();
					}

					// 取消订阅事件
					_signalManager.SignalStateChanged -= OnSignalStateChanged;

					// 释放资源
					_cts.Cancel();
					_cts.Dispose();
				}
				catch (Exception ex)
				{
					_logger.LogError(ex, "释放IO信号应用服务资源异常");
				}
			}

			_disposed = true;
		}
	}
}